Handle NULL start/end pointers
authorHavoc Pennington <hp@pobox.com>
Sat, 30 Sep 2000 17:08:25 +0000 (17:08 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Sat, 30 Sep 2000 17:08:25 +0000 (17:08 +0000)
2000-09-30  Havoc Pennington  <hp@pobox.com>

* gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
NULL start/end pointers

* gtk/gtktextbuffer.c: Write some docs
(gtk_text_buffer_get_selection_bounds): Allow start/end to be
NULL, so you can just check whether there's a selection.

* gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to
cleanup_line or segments_changed ourselves, it gets done
in unlink_segment

* gtk/gtktextmark.h:
s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/

* gtk/gtktextsegment.h: Clean up some indentation and naming mess

* gtk/gtktextmark.c: delete some more old Tk cruft

* gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
mark before removing it, so we can emit MARK_DELETED with a valid
pointer.
(gtk_text_buffer_mark_set): hold ref across signal emission

* gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
whining about attempts to delete special marks

* gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
underscore, since it's internal.

* gtk/gtktextbuffer.h: Remove find_string prototype, this is
now implemented in terms of iterators in gtktextiter.h

* gtk/gtktextbuffer.c (gtk_text_buffer_set_text):
New function, destructively sets contents of buffer. Also
a convenient way to clear the buffer by setting text to ""

* gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
multiline string literal

* gtk/testtext.c (text_changed_callback): Redraw line numbers if
text changes.

* gtk/gtktextiter.c (forward_char): Return FALSE if new location
is not dereferenceable
(gtk_text_iter_forward_lines): fix return value

17 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtktextbtree.c
gtk/gtktextbuffer.c
gtk/gtktextbuffer.h
gtk/gtktextiter.c
gtk/gtktextmark.c
gtk/gtktextmark.h
gtk/gtktextsegment.h
gtk/gtktextview.c
gtk/testtext.c
tests/testtext.c

index 0b50514e953f250882da3fe4c4c2ee77e87b91a6..7442c4411bd9a6bac68a4c5f7bec47dda7599841 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2000-09-30  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
+       NULL start/end pointers
+
+       * gtk/gtktextbuffer.c: Write some docs
+       (gtk_text_buffer_get_selection_bounds): Allow start/end to be
+       NULL, so you can just check whether there's a selection.        
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to 
+       cleanup_line or segments_changed ourselves, it gets done 
+       in unlink_segment
+
+       * gtk/gtktextmark.h:
+       s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/
+       
+       * gtk/gtktextsegment.h: Clean up some indentation and naming mess
+
+       * gtk/gtktextmark.c: delete some more old Tk cruft
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
+       mark before removing it, so we can emit MARK_DELETED with a valid
+       pointer.
+       (gtk_text_buffer_mark_set): hold ref across signal emission
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
+       whining about attempts to delete special marks
+
+       * gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
+       underscore, since it's internal.
+
+       * gtk/gtktextbuffer.h: Remove find_string prototype, this is 
+       now implemented in terms of iterators in gtktextiter.h
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_set_text): 
+       New function, destructively sets contents of buffer. Also 
+       a convenient way to clear the buffer by setting text to ""
+
+       * gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
+       multiline string literal
+
+       * gtk/testtext.c (text_changed_callback): Redraw line numbers if
+       text changes.
+
+       * gtk/gtktextiter.c (forward_char): Return FALSE if new location 
+       is not dereferenceable
+       (gtk_text_iter_forward_lines): fix return value
+
 2000-09-29  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktexttag.c (gtk_text_tag_set_priority): fix indentation
index 0b50514e953f250882da3fe4c4c2ee77e87b91a6..7442c4411bd9a6bac68a4c5f7bec47dda7599841 100644 (file)
@@ -1,3 +1,51 @@
+2000-09-30  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
+       NULL start/end pointers
+
+       * gtk/gtktextbuffer.c: Write some docs
+       (gtk_text_buffer_get_selection_bounds): Allow start/end to be
+       NULL, so you can just check whether there's a selection.        
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to 
+       cleanup_line or segments_changed ourselves, it gets done 
+       in unlink_segment
+
+       * gtk/gtktextmark.h:
+       s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/
+       
+       * gtk/gtktextsegment.h: Clean up some indentation and naming mess
+
+       * gtk/gtktextmark.c: delete some more old Tk cruft
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
+       mark before removing it, so we can emit MARK_DELETED with a valid
+       pointer.
+       (gtk_text_buffer_mark_set): hold ref across signal emission
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
+       whining about attempts to delete special marks
+
+       * gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
+       underscore, since it's internal.
+
+       * gtk/gtktextbuffer.h: Remove find_string prototype, this is 
+       now implemented in terms of iterators in gtktextiter.h
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_set_text): 
+       New function, destructively sets contents of buffer. Also 
+       a convenient way to clear the buffer by setting text to ""
+
+       * gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
+       multiline string literal
+
+       * gtk/testtext.c (text_changed_callback): Redraw line numbers if
+       text changes.
+
+       * gtk/gtktextiter.c (forward_char): Return FALSE if new location 
+       is not dereferenceable
+       (gtk_text_iter_forward_lines): fix return value
+
 2000-09-29  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktexttag.c (gtk_text_tag_set_priority): fix indentation
index 0b50514e953f250882da3fe4c4c2ee77e87b91a6..7442c4411bd9a6bac68a4c5f7bec47dda7599841 100644 (file)
@@ -1,3 +1,51 @@
+2000-09-30  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
+       NULL start/end pointers
+
+       * gtk/gtktextbuffer.c: Write some docs
+       (gtk_text_buffer_get_selection_bounds): Allow start/end to be
+       NULL, so you can just check whether there's a selection.        
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to 
+       cleanup_line or segments_changed ourselves, it gets done 
+       in unlink_segment
+
+       * gtk/gtktextmark.h:
+       s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/
+       
+       * gtk/gtktextsegment.h: Clean up some indentation and naming mess
+
+       * gtk/gtktextmark.c: delete some more old Tk cruft
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
+       mark before removing it, so we can emit MARK_DELETED with a valid
+       pointer.
+       (gtk_text_buffer_mark_set): hold ref across signal emission
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
+       whining about attempts to delete special marks
+
+       * gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
+       underscore, since it's internal.
+
+       * gtk/gtktextbuffer.h: Remove find_string prototype, this is 
+       now implemented in terms of iterators in gtktextiter.h
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_set_text): 
+       New function, destructively sets contents of buffer. Also 
+       a convenient way to clear the buffer by setting text to ""
+
+       * gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
+       multiline string literal
+
+       * gtk/testtext.c (text_changed_callback): Redraw line numbers if
+       text changes.
+
+       * gtk/gtktextiter.c (forward_char): Return FALSE if new location 
+       is not dereferenceable
+       (gtk_text_iter_forward_lines): fix return value
+
 2000-09-29  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktexttag.c (gtk_text_tag_set_priority): fix indentation
index 0b50514e953f250882da3fe4c4c2ee77e87b91a6..7442c4411bd9a6bac68a4c5f7bec47dda7599841 100644 (file)
@@ -1,3 +1,51 @@
+2000-09-30  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
+       NULL start/end pointers
+
+       * gtk/gtktextbuffer.c: Write some docs
+       (gtk_text_buffer_get_selection_bounds): Allow start/end to be
+       NULL, so you can just check whether there's a selection.        
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to 
+       cleanup_line or segments_changed ourselves, it gets done 
+       in unlink_segment
+
+       * gtk/gtktextmark.h:
+       s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/
+       
+       * gtk/gtktextsegment.h: Clean up some indentation and naming mess
+
+       * gtk/gtktextmark.c: delete some more old Tk cruft
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
+       mark before removing it, so we can emit MARK_DELETED with a valid
+       pointer.
+       (gtk_text_buffer_mark_set): hold ref across signal emission
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
+       whining about attempts to delete special marks
+
+       * gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
+       underscore, since it's internal.
+
+       * gtk/gtktextbuffer.h: Remove find_string prototype, this is 
+       now implemented in terms of iterators in gtktextiter.h
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_set_text): 
+       New function, destructively sets contents of buffer. Also 
+       a convenient way to clear the buffer by setting text to ""
+
+       * gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
+       multiline string literal
+
+       * gtk/testtext.c (text_changed_callback): Redraw line numbers if
+       text changes.
+
+       * gtk/gtktextiter.c (forward_char): Return FALSE if new location 
+       is not dereferenceable
+       (gtk_text_iter_forward_lines): fix return value
+
 2000-09-29  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktexttag.c (gtk_text_tag_set_priority): fix indentation
index 0b50514e953f250882da3fe4c4c2ee77e87b91a6..7442c4411bd9a6bac68a4c5f7bec47dda7599841 100644 (file)
@@ -1,3 +1,51 @@
+2000-09-30  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
+       NULL start/end pointers
+
+       * gtk/gtktextbuffer.c: Write some docs
+       (gtk_text_buffer_get_selection_bounds): Allow start/end to be
+       NULL, so you can just check whether there's a selection.        
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to 
+       cleanup_line or segments_changed ourselves, it gets done 
+       in unlink_segment
+
+       * gtk/gtktextmark.h:
+       s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/
+       
+       * gtk/gtktextsegment.h: Clean up some indentation and naming mess
+
+       * gtk/gtktextmark.c: delete some more old Tk cruft
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
+       mark before removing it, so we can emit MARK_DELETED with a valid
+       pointer.
+       (gtk_text_buffer_mark_set): hold ref across signal emission
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
+       whining about attempts to delete special marks
+
+       * gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
+       underscore, since it's internal.
+
+       * gtk/gtktextbuffer.h: Remove find_string prototype, this is 
+       now implemented in terms of iterators in gtktextiter.h
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_set_text): 
+       New function, destructively sets contents of buffer. Also 
+       a convenient way to clear the buffer by setting text to ""
+
+       * gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
+       multiline string literal
+
+       * gtk/testtext.c (text_changed_callback): Redraw line numbers if
+       text changes.
+
+       * gtk/gtktextiter.c (forward_char): Return FALSE if new location 
+       is not dereferenceable
+       (gtk_text_iter_forward_lines): fix return value
+
 2000-09-29  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktexttag.c (gtk_text_tag_set_priority): fix indentation
index 0b50514e953f250882da3fe4c4c2ee77e87b91a6..7442c4411bd9a6bac68a4c5f7bec47dda7599841 100644 (file)
@@ -1,3 +1,51 @@
+2000-09-30  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
+       NULL start/end pointers
+
+       * gtk/gtktextbuffer.c: Write some docs
+       (gtk_text_buffer_get_selection_bounds): Allow start/end to be
+       NULL, so you can just check whether there's a selection.        
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to 
+       cleanup_line or segments_changed ourselves, it gets done 
+       in unlink_segment
+
+       * gtk/gtktextmark.h:
+       s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/
+       
+       * gtk/gtktextsegment.h: Clean up some indentation and naming mess
+
+       * gtk/gtktextmark.c: delete some more old Tk cruft
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
+       mark before removing it, so we can emit MARK_DELETED with a valid
+       pointer.
+       (gtk_text_buffer_mark_set): hold ref across signal emission
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
+       whining about attempts to delete special marks
+
+       * gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
+       underscore, since it's internal.
+
+       * gtk/gtktextbuffer.h: Remove find_string prototype, this is 
+       now implemented in terms of iterators in gtktextiter.h
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_set_text): 
+       New function, destructively sets contents of buffer. Also 
+       a convenient way to clear the buffer by setting text to ""
+
+       * gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
+       multiline string literal
+
+       * gtk/testtext.c (text_changed_callback): Redraw line numbers if
+       text changes.
+
+       * gtk/gtktextiter.c (forward_char): Return FALSE if new location 
+       is not dereferenceable
+       (gtk_text_iter_forward_lines): fix return value
+
 2000-09-29  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktexttag.c (gtk_text_tag_set_priority): fix indentation
index 0b50514e953f250882da3fe4c4c2ee77e87b91a6..7442c4411bd9a6bac68a4c5f7bec47dda7599841 100644 (file)
@@ -1,3 +1,51 @@
+2000-09-30  Havoc Pennington  <hp@pobox.com>
+
+       * gtk/gtktextbtree.c (gtk_text_btree_get_selection_bounds): Handle
+       NULL start/end pointers
+
+       * gtk/gtktextbuffer.c: Write some docs
+       (gtk_text_buffer_get_selection_bounds): Allow start/end to be
+       NULL, so you can just check whether there's a selection.        
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): No need to 
+       cleanup_line or segments_changed ourselves, it gets done 
+       in unlink_segment
+
+       * gtk/gtktextmark.h:
+       s/gtk_text_mark_deleted/gtk_text_mark_get_deleted/
+       
+       * gtk/gtktextsegment.h: Clean up some indentation and naming mess
+
+       * gtk/gtktextmark.c: delete some more old Tk cruft
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_delete_mark): add ref to
+       mark before removing it, so we can emit MARK_DELETED with a valid
+       pointer.
+       (gtk_text_buffer_mark_set): hold ref across signal emission
+
+       * gtk/gtktextbtree.c (gtk_text_btree_remove_mark): improve
+       whining about attempts to delete special marks
+
+       * gtk/gtktextbuffer.c (_gtk_text_buffer_spew): Prepend with
+       underscore, since it's internal.
+
+       * gtk/gtktextbuffer.h: Remove find_string prototype, this is 
+       now implemented in terms of iterators in gtktextiter.h
+
+       * gtk/gtktextbuffer.c (gtk_text_buffer_set_text): 
+       New function, destructively sets contents of buffer. Also 
+       a convenient way to clear the buffer by setting text to ""
+
+       * gtk/gtktextiter.c (gtk_text_iter_make_surreal): reformat
+       multiline string literal
+
+       * gtk/testtext.c (text_changed_callback): Redraw line numbers if
+       text changes.
+
+       * gtk/gtktextiter.c (forward_char): Return FALSE if new location 
+       is not dereferenceable
+       (gtk_text_iter_forward_lines): fix return value
+
 2000-09-29  Havoc Pennington  <hp@redhat.com>
 
        * gtk/gtktexttag.c (gtk_text_tag_set_priority): fix indentation
index 468d5ccaa11a2c35fd99dbc02958232915c66338..7b5985433aa42abaa31b068ec16fce97eeb43037 100644 (file)
@@ -2472,16 +2472,31 @@ gtk_text_btree_get_selection_bounds (GtkTextBTree *tree,
                                     GtkTextIter  *start,
                                     GtkTextIter  *end)
 {
-  gtk_text_btree_get_iter_at_mark (tree, start,
+  GtkTextIter tmp_start, tmp_end;
+  
+  gtk_text_btree_get_iter_at_mark (tree, &tmp_start,
                                    (GtkTextMark*)tree->insert_mark);
-  gtk_text_btree_get_iter_at_mark (tree, end,
+  gtk_text_btree_get_iter_at_mark (tree, &tmp_end,
                                    (GtkTextMark*)tree->selection_bound_mark);
   
-  if (gtk_text_iter_equal(start, end))
-    return FALSE;
+  if (gtk_text_iter_equal(&tmp_start, &tmp_end))
+    {
+      if (start)
+        *start = tmp_start;
+
+      if (end)
+        *end = tmp_end;
+    }
   else
     {
-      gtk_text_iter_reorder(start, end);
+      gtk_text_iter_reorder(&tmp_start, &tmp_end);
+
+      if (start)
+        *start = tmp_start;
+
+      if (end)
+        *end = tmp_end;
+      
       return TRUE;
     }
 }
@@ -2523,27 +2538,25 @@ gtk_text_btree_remove_mark (GtkTextBTree *tree,
 {
   GtkTextLineSegment *segment = (GtkTextLineSegment*) mark;
   
-  g_return_if_fail(segment != NULL);
-  g_return_if_fail(segment != tree->selection_bound_mark);
-  g_return_if_fail(segment != tree->insert_mark);
-  g_return_if_fail(tree != NULL);
+  g_return_if_fail (segment != NULL);
+  g_return_if_fail (tree != NULL);
 
   if (segment->body.mark.not_deleteable)
     {
       g_warning("Can't delete special mark `%s'", segment->body.mark.name);
       return;
     }
+
+  /* This calls cleanup_line and segments_changed */
+  gtk_text_btree_unlink_segment (tree, segment, segment->body.mark.line);
   
-  gtk_text_btree_unlink_segment(tree, segment, segment->body.mark.line);
-  /* FIXME should probably cleanup_line but Tk didn't */
   if (segment->body.mark.name)
-    g_hash_table_remove(tree->mark_table, segment->body.mark.name);
-  mark_segment_unref(segment);
+    g_hash_table_remove (tree->mark_table, segment->body.mark.name);
+  
+  mark_segment_unref (segment);
 
   segment->body.mark.tree = NULL;
   segment->body.mark.line = NULL;
-  
-  segments_changed(tree);
 }
 
 gboolean
index 6358e94fe6e9f6a24108eb17f123cc69808a2a1d..a83345b3ce9bd05667aed2adefb5fa8ff3edb05b 100644 (file)
@@ -348,6 +348,48 @@ gtk_text_buffer_get_tag_table (GtkTextBuffer  *buffer)
   return get_table (buffer);
 }
 
+/**
+ * gtk_text_buffer_set_text:
+ * @buffer: a #GtkTextBuffer
+ * @text: UTF-8 text to insert
+ * @len: length of @text in bytes
+ * 
+ * Deletes current contents of @buffer, and inserts @text instead.  If
+ * @text doesn't end with a newline, a newline is added;
+ * #GtkTextBuffer contents must always end with a newline. If @text
+ * ends with a newline, the new buffer contents will be exactly
+ * @text. If @len is -1, @text must be nul-terminated.
+ **/
+void
+gtk_text_buffer_set_text (GtkTextBuffer *buffer,
+                          const gchar   *text,
+                          gint           len)
+{
+  GtkTextIter start, end;
+  
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (text != NULL);
+
+  if (len < 0)
+    len = strlen (text);
+
+  /* Chop newline, since the buffer will already have one
+   * in it.
+   */
+  if (len > 0 && text[len-1] == '\n')
+    len -= 1;
+
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+  
+  gtk_text_buffer_delete (buffer, &start, &end);
+
+  if (len > 0)
+    {
+      gtk_text_buffer_get_iter_at_offset (buffer, &start, 0);
+      gtk_text_buffer_insert (buffer, &start, text, len);
+    }
+}
+
 /*
  * Insertion
  */
@@ -510,6 +552,178 @@ gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
                                              default_editable);
 }
 
+
+/**
+ * gtk_text_buffer_insert_range:
+ * @buffer: a #GtkTextBuffer
+ * @iter: a position in @buffer
+ * @start: a position in a #GtkTextBuffer
+ * @end: another position in the same buffer as @start
+ *
+ * Copies text, tags, and pixbufs between @start and @end (the order
+ * of @start and @end doesn't matter) and inserts the copy at @iter.
+ * Used instead of simply getting/inserting text because it preserves
+ * images and tags. If @start and @end are in a different buffer
+ * from @buffer, the two buffers must share the same tag table.
+ *
+ * Implemented via multiple emissions of the insert_text and
+ * apply_tag signals, so expect those.
+ **/
+void
+gtk_text_buffer_insert_range (GtkTextBuffer     *buffer,
+                              GtkTextIter       *iter,
+                              const GtkTextIter *start,
+                              const GtkTextIter *end)
+{
+  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (start != NULL);
+  g_return_if_fail (end != NULL);
+  g_return_if_fail (gtk_text_iter_get_buffer (start) !=
+                    gtk_text_iter_get_buffer (end));
+  g_return_if_fail (gtk_text_iter_get_buffer (start)->tag_table !=
+                    buffer->tag_table);
+
+  /* FIXME */
+}
+
+gboolean
+gtk_text_buffer_insert_range_interactive (GtkTextBuffer     *buffer,
+                                          GtkTextIter       *iter,
+                                          const GtkTextIter *start,
+                                          const GtkTextIter *end,
+                                          gboolean           default_editable)
+{
+  g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
+  g_return_val_if_fail (iter != NULL, FALSE);
+  g_return_val_if_fail (start != NULL, FALSE);
+  g_return_val_if_fail (end != NULL, FALSE);
+  g_return_val_if_fail (gtk_text_iter_get_buffer (start) !=
+                        gtk_text_iter_get_buffer (end), FALSE);
+  g_return_val_if_fail (gtk_text_iter_get_buffer (start)->tag_table !=
+                        buffer->tag_table, FALSE);
+
+
+  /* FIXME */
+  
+  return FALSE;
+}
+
+/**
+ * gtk_text_buffer_insert_with_tags:
+ * @buffer: a #GtkTextBuffer
+ * @iter: an iterator in @buffer
+ * @text: UTF-8 text
+ * @len: length of @text, or -1 
+ * @first_tag: first tag to apply to @text
+ * @Varargs: NULL-terminated list of tags to apply 
+ * 
+ * Inserts @text into @buffer at @iter, applying the list of tags to
+ * the newly-inserted text. The last tag specified must be NULL to
+ * terminate the list. Equivalent to calling gtk_text_buffer_insert(),
+ * then gtk_text_buffer_apply_tag() on the inserted text;
+ * gtk_text_buffer_insert_with_tags() is just a convenience function.
+ **/
+void
+gtk_text_buffer_insert_with_tags (GtkTextBuffer *buffer,
+                                  GtkTextIter   *iter,
+                                  const gchar   *text,
+                                  gint           len,
+                                  GtkTextTag    *first_tag,
+                                  ...)
+{
+  gint start_offset;
+  GtkTextIter start;
+  va_list args;
+  GtkTextTag *tag;
+  
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (text != NULL);
+
+  start_offset = gtk_text_iter_get_offset (iter);
+  
+  gtk_text_buffer_insert (buffer, iter, text, len);
+
+  if (first_tag == NULL)
+    return;
+  
+  gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
+  
+  va_start (args, first_tag);
+  tag = first_tag;
+  while (tag)
+    {
+      gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
+
+      tag = va_arg (args, GtkTextTag*);
+    }
+
+  va_end (args);
+}
+
+/**
+ * gtk_text_buffer_insert_with_tags_by_name:
+ * @buffer: a #GtkTextBuffer
+ * @iter: position in @buffer
+ * @text: UTF-8 text
+ * @len: length of @text, or -1
+ * @first_tag_name: name of a tag to apply to @text
+ * @Varargs: more tag names
+ * 
+ * Same as gtk_text_buffer_insert_with_tags(), but allows you
+ * to pass in tag names instead of tag objects.
+ **/
+void
+gtk_text_buffer_insert_with_tags_by_name  (GtkTextBuffer *buffer,
+                                           GtkTextIter   *iter,
+                                           const gchar   *text,
+                                           gint           len,
+                                           const gchar   *first_tag_name,
+                                           ...)
+{
+  gint start_offset;
+  GtkTextIter start;
+  va_list args;
+  const gchar *tag_name;
+  
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (text != NULL);
+
+  start_offset = gtk_text_iter_get_offset (iter);
+  
+  gtk_text_buffer_insert (buffer, iter, text, len);
+
+  if (first_tag_name == NULL)
+    return;
+  
+  gtk_text_buffer_get_iter_at_offset (buffer, &start, start_offset);
+  
+  va_start (args, first_tag_name);
+  tag_name = first_tag_name;
+  while (tag_name)
+    {
+      GtkTextTag *tag;
+
+      tag = gtk_text_tag_table_lookup (buffer->tag_table,
+                                       tag_name);
+
+      if (tag == NULL)
+        {
+          g_warning ("%s: no tag with name '%s'!", G_STRLOC, tag_name);
+          return;
+        }
+      
+      gtk_text_buffer_apply_tag (buffer, tag, &start, iter);
+
+      tag_name = va_arg (args, const gchar*);
+    }
+
+  va_end (args);
+}
+
+
 /*
  * Deletion
  */
@@ -535,10 +749,10 @@ gtk_text_buffer_real_delete_text(GtkTextBuffer *buffer,
 }
 
 static void
-gtk_text_buffer_emit_delete(GtkTextBuffer *buffer,
-                            GtkTextIter *start,
-                            GtkTextIter *end,
-                            gboolean interactive)
+gtk_text_buffer_emit_delete (GtkTextBuffer *buffer,
+                             GtkTextIter *start,
+                             GtkTextIter *end,
+                             gboolean interactive)
 {
   g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
   g_return_if_fail(start != NULL);
@@ -549,11 +763,14 @@ gtk_text_buffer_emit_delete(GtkTextBuffer *buffer,
 
   gtk_text_iter_reorder (start, end);
 
-  /* FIXME if the final newline is in the deletion range,
-   * shorten the range. (i.e. if end is the end iterator,
-   * move it backward by one)
+  /* Somewhat annoyingly, if you try to delete the final newline
+   * the BTree will put it back; which means you can't deduce the
+   * final contents of the buffer purely by monitoring insert/delete
+   * signals on the buffer. But if you delete the final newline, any
+   * tags on the newline will go away, oddly. See comment in
+   * gtktextbtree.c. This is all sort of annoying, but really hard
+   * to fix.
    */
-  
   gtk_signal_emit(GTK_OBJECT(buffer),
                   signals[DELETE_TEXT],
                   start, end,
@@ -822,11 +1039,15 @@ gtk_text_buffer_mark_set (GtkTextBuffer     *buffer,
      override the default handler or stop the emission; that is,
      this signal is purely for notification, and not to allow users
      to modify the default behavior. */
+
+  gtk_text_mark_ref (mark);
+  
   gtk_signal_emit(GTK_OBJECT(buffer),
                   signals[MARK_SET],
                   location,
                   mark);
 
+  gtk_text_mark_unref (mark);
 }
 
 /**
@@ -841,15 +1062,15 @@ gtk_text_buffer_mark_set (GtkTextBuffer     *buffer,
  * 
  * Move the mark to the given position, if not @should_exist, create the mark.
  * 
- * Return value: 
+ * Return value: mark
  **/
 static GtkTextMark*
-gtk_text_buffer_set_mark(GtkTextBuffer *buffer,
-                         GtkTextMark *existing_mark,
-                         const gchar *mark_name,
-                         const GtkTextIter *iter,
-                         gboolean left_gravity,
-                         gboolean should_exist)
+gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
+                          GtkTextMark *existing_mark,
+                          const gchar *mark_name,
+                          const GtkTextIter *iter,
+                          gboolean left_gravity,
+                          gboolean should_exist)
 {
   GtkTextIter location;
   GtkTextMark *mark;
@@ -862,14 +1083,14 @@ gtk_text_buffer_set_mark(GtkTextBuffer *buffer,
                                  should_exist);
 
   if (gtk_text_btree_mark_is_insert(get_btree (buffer), mark) ||
-      gtk_text_btree_mark_is_selection_bound(get_btree (buffer), mark))
+      gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
     {
-      gtk_text_buffer_update_primary_selection(buffer);
+      gtk_text_buffer_update_primary_selection (buffer);
     }
   
-  gtk_text_btree_get_iter_at_mark(get_btree (buffer),
-                                  &location,
-                                  mark);
+  gtk_text_btree_get_iter_at_mark (get_btree (buffer),
+                                   &location,
+                                   mark);
   
   gtk_text_buffer_mark_set (buffer, &location, mark);
 
@@ -895,7 +1116,11 @@ gtk_text_buffer_set_mark(GtkTextBuffer *buffer,
  *
  * The caller of this function does <emphasis>not</emphasis> own a reference
  * to the returned #GtkTextMark, so you can ignore the return value
- * if you like.
+ * if you like. Marks are owned by the buffer and go away when the
+ * buffer does.
+ *
+ * Emits the "mark_set" signal as notification of the mark's initial
+ * placement.
  * 
  * Return value: the new #GtkTextMark object
  **/
@@ -905,90 +1130,219 @@ gtk_text_buffer_create_mark(GtkTextBuffer *buffer,
                             const GtkTextIter *where,
                             gboolean left_gravity)
 {
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
+  g_return_val_if_fail (GTK_IS_TEXT_BUFFER(buffer), NULL);
   
-  return gtk_text_buffer_set_mark(buffer, NULL, mark_name, where,
-                                  left_gravity, FALSE);
+  return gtk_text_buffer_set_mark (buffer, NULL, mark_name, where,
+                                   left_gravity, FALSE);
 }
 
 /**
  * gtk_text_buffer_move_mark:
- * @buffer: 
- * @mark: 
- * @where: 
- * 
+ * @buffer: a #GtkTextBuffer
+ * @mark: a #GtkTextMark
+ * @where: new location for @mark in @buffer
  * 
+ * Moves @mark to the new location @where. Emits the "mark_set" signal
+ * as notification of the move.
  **/
 void
-gtk_text_buffer_move_mark(GtkTextBuffer *buffer,
-                          GtkTextMark *mark,
-                          const GtkTextIter *where)
+gtk_text_buffer_move_mark (GtkTextBuffer *buffer,
+                           GtkTextMark *mark,
+                           const GtkTextIter *where)
 {
   g_return_if_fail (mark != NULL);
-  g_return_if_fail (!gtk_text_mark_deleted (mark));
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (!gtk_text_mark_get_deleted (mark));
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
   
-  gtk_text_buffer_set_mark(buffer, mark, NULL, where, FALSE, TRUE);
+  gtk_text_buffer_set_mark (buffer, mark, NULL, where, FALSE, TRUE);
 }
 
+/**
+ * gtk_text_buffer_get_iter_at_mark:
+ * @buffer: a #GtkTextBuffer
+ * @iter: iterator to initialize
+ * @mark: a #GtkTextMark in @buffer
+ * 
+ * Initializes @iter with the current position of @mark.
+ **/
 void
-gtk_text_buffer_get_iter_at_mark(GtkTextBuffer *buffer,
-                                 GtkTextIter *iter,
-                                 GtkTextMark *mark)
+gtk_text_buffer_get_iter_at_mark (GtkTextBuffer *buffer,
+                                  GtkTextIter *iter,
+                                  GtkTextMark *mark)
 {
   g_return_if_fail (mark != NULL);
-  g_return_if_fail (!gtk_text_mark_deleted (mark));
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (!gtk_text_mark_get_deleted (mark));
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
 
-  gtk_text_btree_get_iter_at_mark(get_btree (buffer),
-                                  iter,
-                                  mark);
+  gtk_text_btree_get_iter_at_mark (get_btree (buffer),
+                                   iter,
+                                   mark);
 }
 
+/**
+ * gtk_text_buffer_delete_mark:
+ * @buffer: a #GtkTextBuffer
+ * @mark: a #GtkTextMark in @buffer 
+ * 
+ * Deletes @mark, so that it's no longer located anywhere in the
+ * buffer. Removes the reference the buffer holds to the mark, so if
+ * you haven't called gtk_text_mark_ref() the mark will be freed. Even
+ * if the mark isn't freed, most operations on @mark become
+ * invalid. There is no way to undelete a
+ * mark. gtk_text_mark_get_deleted() will return TRUE after this
+ * function has been called on a mark; gtk_text_mark_get_deleted()
+ * indicates that a mark no longer belongs to a buffer. The "mark_deleted"
+ * signal will be emitted as notification after the mark is deleted.
+ **/
 void
 gtk_text_buffer_delete_mark(GtkTextBuffer *buffer,
-                            GtkTextMark *mark)
+                            GtkTextMark   *mark)
 {
   g_return_if_fail (mark != NULL);
-  g_return_if_fail (!gtk_text_mark_deleted (mark));
-  g_return_if_fail(GTK_IS_TEXT_BUFFER(buffer));
-
+  g_return_if_fail (!gtk_text_mark_get_deleted (mark));
+  g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+  
+  gtk_text_mark_ref (mark);
+  
   gtk_text_btree_remove_mark (get_btree (buffer), mark);
 
   /* See rationale above for MARK_SET on why we emit this after
-     removing the mark, rather than removing the mark in a default
-     handler. */
-  gtk_signal_emit(GTK_OBJECT(buffer), signals[MARK_DELETED],
-                  mark);
+   * removing the mark, rather than removing the mark in a default
+   * handler.
+   */
+  gtk_signal_emit (GTK_OBJECT(buffer), signals[MARK_DELETED],
+                   mark);
+
+  gtk_text_mark_unref (mark);
 }
 
+/**
+ * gtk_text_buffer_get_mark:
+ * @buffer: a #GtkTextBuffer
+ * @name: a mark name
+ * 
+ * Returns the mark named @name in buffer @buffer, or NULL if no such
+ * mark exists in the buffer.
+ * 
+ * Return value: a #GtkTextMark, or NULL
+ **/
 GtkTextMark*
 gtk_text_buffer_get_mark (GtkTextBuffer      *buffer,
                           const gchar         *name)
 {
   GtkTextMark *mark;
 
-  g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
-  g_return_val_if_fail(name != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_TEXT_BUFFER(buffer), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
   
-  mark = gtk_text_btree_get_mark_by_name(get_btree (buffer), name);
+  mark = gtk_text_btree_get_mark_by_name (get_btree (buffer), name);
 
   return mark;
 }
 
+
+/**
+ * gtk_text_buffer_move_mark_by_name:
+ * @buffer: a #GtkTextBuffer 
+ * @name: name of a mark
+ * @where: new location for mark
+ * 
+ * Moves the mark named @name (which must exist) to location @where.
+ * See gtk_text_buffer_move_mark() for details.
+ **/
+void
+gtk_text_buffer_move_mark_by_name (GtkTextBuffer     *buffer,
+                                   const gchar       *name,
+                                   const GtkTextIter *where)
+{
+  GtkTextMark *mark;
+
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (name != NULL);
+  
+  mark = gtk_text_btree_get_mark_by_name (get_btree (buffer), name);  
+
+  if (mark == NULL)
+    {
+      g_warning ("%s: no mark named '%s'", G_STRLOC, name);
+      return;
+    }
+  
+  gtk_text_buffer_move_mark (buffer, mark, where);
+}
+
+/**
+ * gtk_text_buffer_delete_mark_by_name:
+ * @buffer: a #GtkTextBuffer
+ * @name: name of a mark in @buffer
+ * 
+ * Deletes the mark named @name; the mark must exist. See
+ * gtk_text_buffer_delete_mark() for details.
+ **/
+void
+gtk_text_buffer_delete_mark_by_name (GtkTextBuffer     *buffer,
+                                     const gchar       *name)
+{
+  GtkTextMark *mark;
+
+  g_return_if_fail (GTK_IS_TEXT_BUFFER(buffer));
+  g_return_if_fail (name != NULL);
+  
+  mark = gtk_text_btree_get_mark_by_name (get_btree (buffer), name);  
+
+  if (mark == NULL)
+    {
+      g_warning ("%s: no mark named '%s'", G_STRLOC, name);
+      return;
+    }
+  
+  gtk_text_buffer_delete_mark (buffer, mark);
+}
+
+/**
+ * gtk_text_buffer_get_insert:
+ * @buffer: a #GtkTextBuffer
+ * 
+ * Returns the mark that represents the cursor (insertion point).
+ * Equivalent to calling gtk_text_buffer_get_mark() to get the mark
+ * name "insert," but very slightly more efficient, and involves less
+ * typing.
+ * 
+ * Return value: insertion point mark
+ **/
 GtkTextMark*
 gtk_text_buffer_get_insert (GtkTextBuffer *buffer)
 {
   g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
 
+  /* FIXME use struct member in btree */
   return gtk_text_buffer_get_mark (buffer, "insert");
 }
 
+/**
+ * gtk_text_buffer_get_selection_bound:
+ * @buffer: a #GtkTextBuffer
+ * 
+ * Returns the mark that represents the selection bound.  Equivalent
+ * to calling gtk_text_buffer_get_mark() to get the mark name
+ * "selection_bound," but very slightly more efficient, and involves
+ * less typing.
+ *
+ * The currently-selected text in @buffer is the region between the
+ * "selection_bound" and "insert" marks. If "selection_bound" and
+ * "insert" are in the same place, then there is no current selection.
+ * gtk_text_buffer_get_selection_bounds() is another convenient function
+ * for handling the selection, if you just want to know whether there's a
+ * selection and what its bounds are.
+ * 
+ * Return value: selection bound mark
+ **/
 GtkTextMark*
 gtk_text_buffer_get_selection_bound (GtkTextBuffer *buffer)
 {
   g_return_val_if_fail(GTK_IS_TEXT_BUFFER(buffer), NULL);
 
+  /* FIXME use struct member in btree */
   return gtk_text_buffer_get_mark (buffer, "selection_bound");
 }
 
@@ -1000,9 +1354,10 @@ gtk_text_buffer_get_selection_bound (GtkTextBuffer *buffer)
  * This function moves the "insert" and "selection_bound" marks
  * simultaneously.  If you move them to the same place in two steps
  * with gtk_text_buffer_move_mark(), you will temporarily select a
- * region in between their old and new locations, which marks part of
- * the buffer invalid and can be inefficient. This function moves
- * them as a unit, which can be optimized.
+ * region in between their old and new locations, which can be pretty
+ * inefficient since the temporarily-selected region will force stuff
+ * to be recalculated. This function moves them as a unit, which can
+ * be optimized.
  **/
 void
 gtk_text_buffer_place_cursor (GtkTextBuffer     *buffer,
@@ -1017,7 +1372,7 @@ gtk_text_buffer_place_cursor (GtkTextBuffer     *buffer,
   if (gtk_text_iter_is_last (&real))
     gtk_text_iter_prev_char (&real);
   
-  gtk_text_btree_place_cursor(get_btree (buffer), &real);
+  gtk_text_btree_place_cursor (get_btree (buffer), &real);
   gtk_text_buffer_mark_set (buffer, &real,
                             gtk_text_buffer_get_mark (buffer,
                                                       "insert"));
@@ -1384,7 +1739,7 @@ clipboard_received (GtkClipboard *clipboard,
       GtkTextMark *paste_point_override;
 
       paste_point_override = gtk_text_buffer_get_mark (buffer,
-                                                      "__paste_point_override");
+                                                      "gtk_paste_point_override");
       
       if (paste_point_override != NULL)
        {
@@ -1392,7 +1747,7 @@ clipboard_received (GtkClipboard *clipboard,
                                           paste_point_override);
          gtk_text_buffer_delete_mark(buffer,
                                      gtk_text_buffer_get_mark (buffer,
-                                                               "__paste_point_override"));
+                                                               "gtk_paste_point_override"));
        }
       else
        {
@@ -1503,7 +1858,7 @@ gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
 {
   if (override_location != NULL)
     gtk_text_buffer_create_mark(buffer,
-                                "__paste_point_override",
+                                "gtk_paste_point_override",
                                 override_location, FALSE);
   
   paste (buffer, FALSE, TRUE, default_editable);
@@ -1580,7 +1935,8 @@ cut_or_copy(GtkTextBuffer *buffer,
       if (delete_region_after)
         {
           if (interactive)
-            gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable);
+            gtk_text_buffer_delete_interactive (buffer, &start, &end,
+                                                default_editable);
           else
             gtk_text_buffer_delete (buffer, &start, &end);
         }
@@ -1601,12 +1957,26 @@ gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer)
 }
 
 
+/**
+ * gtk_text_buffer_get_selection_bounds:
+ * @buffer: a #GtkTextBuffer
+ * @start: iterator to initialize with selection start
+ * @end: iterator to initialize with selection end
+ * 
+ * Returns %TRUE if some text is selected; places the bounds
+ * of the selection in @start and @end (if the selection has length 0,
+ * then @start and @end are filled in with the same value).
+ * @start and @end will be in ascending order. If @start and @end are
+ * NULL, then they are not filled in, but the return value still indicates
+ * whether text is selected.
+ * 
+ * Return value: whether the selection has nonzero length
+ **/
 gboolean
 gtk_text_buffer_get_selection_bounds   (GtkTextBuffer      *buffer,
                                         GtkTextIter        *start,
                                         GtkTextIter        *end)
 {
-  g_return_val_if_fail (buffer != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
 
   return gtk_text_btree_get_selection_bounds (get_btree (buffer), start, end);
@@ -1618,8 +1988,12 @@ gtk_text_buffer_get_selection_bounds   (GtkTextBuffer      *buffer,
  */
 
 void
-gtk_text_buffer_spew(GtkTextBuffer *buffer)
+_gtk_text_buffer_spew(GtkTextBuffer *buffer)
 {
   gtk_text_btree_spew(get_btree (buffer));
 }
 
+
+
+
+
index 836010eebc584caca96cddab37b128f6cefc499c..ef50bb96c921d3f41a065fb6be3d101160ca3e8c 100644 (file)
@@ -91,6 +91,11 @@ gint           gtk_text_buffer_get_char_count (GtkTextBuffer   *buffer);
 
 GtkTextTagTable* gtk_text_buffer_get_tag_table (GtkTextBuffer  *buffer);
 
+/* Delete whole buffer, then insert */
+void gtk_text_buffer_set_text          (GtkTextBuffer *buffer,
+                                        const gchar   *text,
+                                        gint           len);
+
 /* Insert into the buffer */
 void gtk_text_buffer_insert            (GtkTextBuffer *buffer,
                                         GtkTextIter   *iter,
@@ -110,6 +115,29 @@ gboolean gtk_text_buffer_insert_interactive_at_cursor (GtkTextBuffer *buffer,
                                                        gint           len,
                                                        gboolean       default_editable);
 
+void     gtk_text_buffer_insert_range             (GtkTextBuffer     *buffer,
+                                                   GtkTextIter       *iter,
+                                                   const GtkTextIter *start,
+                                                   const GtkTextIter *end);
+gboolean gtk_text_buffer_insert_range_interactive (GtkTextBuffer     *buffer,
+                                                   GtkTextIter       *iter,
+                                                   const GtkTextIter *start,
+                                                   const GtkTextIter *end,
+                                                   gboolean           default_editable);
+
+void    gtk_text_buffer_insert_with_tags          (GtkTextBuffer     *buffer,
+                                                   GtkTextIter       *iter,
+                                                   const gchar       *text,
+                                                   gint               len,
+                                                   GtkTextTag        *first_tag,
+                                                   ...);
+
+void    gtk_text_buffer_insert_with_tags_by_name  (GtkTextBuffer     *buffer,
+                                                   GtkTextIter       *iter,
+                                                   const gchar       *text,
+                                                   gint               len,
+                                                   const gchar       *first_tag_name,
+                                                   ...);
 
 /* Delete from the buffer */
 void     gtk_text_buffer_delete             (GtkTextBuffer *buffer,
@@ -151,6 +179,12 @@ void           gtk_text_buffer_delete_mark (GtkTextBuffer     *buffer,
 GtkTextMark*   gtk_text_buffer_get_mark    (GtkTextBuffer     *buffer,
                                             const gchar       *name);
 
+void gtk_text_buffer_move_mark_by_name   (GtkTextBuffer     *buffer,
+                                          const gchar       *name,
+                                          const GtkTextIter *where);
+void gtk_text_buffer_delete_mark_by_name (GtkTextBuffer     *buffer,
+                                          const gchar       *name);
+
 GtkTextMark* gtk_text_buffer_get_insert          (GtkTextBuffer *buffer);
 GtkTextMark* gtk_text_buffer_get_selection_bound (GtkTextBuffer *buffer);
 
@@ -242,23 +276,8 @@ gboolean        gtk_text_buffer_delete_selection        (GtkTextBuffer *buffer,
                                                          gboolean       interactive,
                                                          gboolean       default_editable);
 
-/* This function is not implemented. */
-gboolean gtk_text_buffer_find_string(GtkTextBuffer *buffer,
-                                     GtkTextIter *iter,
-                                     const gchar *str,
-                                     const GtkTextIter *start,
-                                     const GtkTextIter *end);
-
-#if 0
-/* Waiting on glib 1.4 regexp facility */
-gboolean gtk_text_buffer_find_regexp(GtkTextBuffer *buffer,
-                                     GRegexp *regexp,
-                                     const GtkTextIter *start,
-                                     const GtkTextIter *end);
-#endif
-
 /* INTERNAL private stuff */
-void            gtk_text_buffer_spew                   (GtkTextBuffer      *buffer);
+void            _gtk_text_buffer_spew                  (GtkTextBuffer      *buffer);
 
 GtkTextBTree*   _gtk_text_buffer_get_btree             (GtkTextBuffer      *buffer);
 
index cad7b9cf5a941df7dff2f0e41d64cb98e4120c19..bc44e02ac48602f4fd2c3cf941da002b82e1c1bc 100644 (file)
@@ -125,7 +125,13 @@ gtk_text_iter_make_surreal(const GtkTextIter *_iter)
   if (iter->chars_changed_stamp !=
       gtk_text_btree_get_chars_changed_stamp(iter->tree))
     {
-      g_warning("Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixmaps/widgets in the buffer have been modified since the iterator was created.\nYou must use marks, character numbers, or line numbers to preserve a position across buffer modifications.\nYou can apply tags and insert marks without invalidating your iterators, however.");
+      g_warning("Invalid text buffer iterator: either the iterator "
+                "is uninitialized, or the characters/pixbufs/widgets "
+                "in the buffer have been modified since the iterator "
+                "was created.\nYou must use marks, character numbers, "
+                "or line numbers to preserve a position across buffer "
+                "modifications.\nYou can apply tags and insert marks "
+                "without invalidating your iterators, however.");
       return NULL;
     }
 
@@ -335,7 +341,7 @@ static void
 check_invariants(const GtkTextIter *iter)
 {
   if (gtk_debug_flags & GTK_DEBUG_TEXT)
-    gtk_text_iter_check(iter);
+    gtk_text_iter_check (iter);
 }
 #else
 #define check_invariants(x)
@@ -1410,6 +1416,9 @@ forward_line_leaving_caches_unmodified(GtkTextRealIter *real)
     }
 }
 
+/* The return value indicates (MOVEMENT OCCURRED && NEW ITER IS
+ * DEREFERENCEABLE)
+ */
 static gboolean
 forward_char(GtkTextRealIter *real)
 {
@@ -1459,11 +1468,10 @@ forward_char(GtkTextRealIter *real)
       
       check_invariants((GtkTextIter*)real);
 
-      /* FIXME we don't currently return FALSE if
-       * we moved onto the end iterator
-       */
-      
-      return TRUE;
+      if (gtk_text_iter_is_last ((GtkTextIter*)real))
+        return FALSE;
+      else
+        return TRUE;
     }
 }
 
@@ -1653,14 +1661,12 @@ gtk_text_iter_prev_char(GtkTextIter *iter)
  * 
  * Moves @count characters if possible (if @count would move past the
  * start or end of the buffer, moves to the start or end of the
- * buffer). If @count is positive, the return value indicates whether
- * @iter was moved to a dereferenceable location (FALSE is returned if
- * @iter was moved to the non-dereferenceable end iterator). If @count
- * is negative, the return value indicates whether @iter was already
- * at character offset 0. If @count is 0, the function does nothing
- * and returns FALSE.
- * 
- * Return value: whether @iter moved or is dereferenceable
+ * buffer). The return value indicates whether the new position of
+ * @iter is different from its original position, and dereferenceable
+ * (the last iterator in the buffer is not dereferenceable). If @count
+ * is 0, the function does nothing and returns FALSE.
+ * 
+ * Return value: whether @iter moved and is dereferenceable
  **/
 gboolean
 gtk_text_iter_forward_chars(GtkTextIter *iter, gint count)
@@ -1724,14 +1730,12 @@ gtk_text_iter_forward_chars(GtkTextIter *iter, gint count)
  *
  * Moves @count characters backward, if possible (if @count would move
  * past the start or end of the buffer, moves to the start or end of
- * the buffer). If @count is negative, the return value indicates
- * whether @iter was moved to a dereferenceable location (FALSE is
- * returned if @iter was moved to the non-dereferenceable end
- * iterator). If @count is positive, the return value indicates
- * whether @iter was already at character offset 0. If @count is 0,
+ * the buffer).  The return value indicates whether the iterator moved
+ * onto a dereferenceable position; if the iterator didn't move, or
+ * moved onto the end iterator, then FALSE is returned. If @count is 0,
  * the function does nothing and returns FALSE.
  * 
- * Return value: whether @iter moved or is dereferenceable
+ * Return value: whether @iter moved and is dereferenceable
  *  
  **/
 gboolean
@@ -1748,7 +1752,7 @@ gtk_text_iter_backward_chars(GtkTextIter *iter, gint count)
   else if (count == 0)
     return FALSE;
   else if (count < 0)
-    return gtk_text_iter_forward_chars(iter, 0 - count);
+    return gtk_text_iter_forward_chars (iter, 0 - count);
 
   ensure_char_offsets(real);
   check_invariants(iter);
@@ -1818,7 +1822,8 @@ gtk_text_iter_backward_chars(GtkTextIter *iter, gint count)
  * 
  * Moves @iter to the start of the next line. Returns TRUE if there
  * was a next line to move to, and FALSE if @iter was simply moved to
- * the end of the buffer and is now not dereferenceable.
+ * the end of the buffer and is now not dereferenceable, or if @iter was
+ * already at the end of the buffer.
  * 
  * Return value: whether @iter can be dereferenced
  **/
@@ -1863,7 +1868,9 @@ gtk_text_iter_forward_line(GtkTextIter *iter)
  * @iter could be moved; i.e. if @iter was at character offset 0, this
  * function returns FALSE. Therefore if @iter was already on line 0,
  * but not at the start of the line, @iter is snapped to the start of
- * the line and the function returns TRUE.
+ * the line and the function returns TRUE. (Note that this implies that
+ * in a loop calling this function, the line number may not change on
+ * every iteration, if your first iteration is on line 0.)
  * 
  * Return value: whether @iter moved
  **/
@@ -1921,7 +1928,8 @@ gtk_text_iter_backward_line(GtkTextIter *iter)
      of the first line and return TRUE, so TRUE means the
      iterator changed, not that the line changed; this is maybe
      a bit weird. I'm not sure there's an obvious right thing
-     to do though. */
+     to do though.
+  */
 
   check_invariants(iter);
   
@@ -1932,13 +1940,13 @@ gboolean
 gtk_text_iter_forward_lines(GtkTextIter *iter, gint count)
 {
   if (count < 0)
-    return gtk_text_iter_backward_lines(iter, 0 - count);
+    return gtk_text_iter_backward_lines (iter, 0 - count);
   else if (count == 0)
     return FALSE;
   else if (count == 1)
     {
       check_invariants(iter);
-      return gtk_text_iter_forward_line(iter);
+      return gtk_text_iter_forward_line (iter);
     }
   else
     {
@@ -1950,10 +1958,10 @@ gtk_text_iter_forward_lines(GtkTextIter *iter, gint count)
 
       check_invariants(iter);
 
-      /* FIXME this needs to return FALSE if we moved onto the
-       * end iterator.
-       */
-      return (gtk_text_iter_get_line(iter) != old_line);
+      /* return whether it moved, and is dereferenceable. */
+      return
+        (gtk_text_iter_get_line (iter) != old_line) &&
+        !gtk_text_iter_is_last (iter);
     }
 }
 
@@ -2149,7 +2157,7 @@ gtk_text_iter_forward_word_ends(GtkTextIter      *iter,
 
 gboolean
 gtk_text_iter_backward_word_starts(GtkTextIter      *iter,
-                                    gint               count)
+                                   gint               count)
 {
   g_return_val_if_fail(iter != NULL, FALSE);
   g_return_val_if_fail(count > 0, FALSE);
@@ -2169,7 +2177,7 @@ gtk_text_iter_backward_word_starts(GtkTextIter      *iter,
 
 void
 gtk_text_iter_set_line_offset(GtkTextIter *iter,
-                             gint char_on_line)
+                              gint char_on_line)
 {
   GtkTextRealIter *real;
   
@@ -2295,6 +2303,19 @@ gtk_text_iter_forward_to_newline(GtkTextIter *iter)
     }
 }
 
+/**
+ * gtk_text_iter_forward_to_tag_toggle:
+ * @iter: a #GtkTextIter
+ * @tag: a #GtkTextTag, or NULL
+ * 
+ * Moves forward to the next toggle (on or off) of the
+ * #GtkTextTag @tag, or to the next toggle of any tag if
+ * @tag is NULL. If no matching tag toggles are found,
+ * returns FALSE, otherwise TRUE. Does not return toggles
+ * located at @iter, only toggles after @iter.
+ * 
+ * Return value: whether we found a tag toggle after @iter
+ **/
 gboolean
 gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
                                      GtkTextTag  *tag)
@@ -2314,7 +2335,7 @@ gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
   
   current_line = real->line;
   next_line = gtk_text_line_next_could_contain_tag(current_line,
-                                                    real->tree, tag);
+                                                   real->tree, tag);
   
   while (gtk_text_iter_forward_indexable_segment(iter))
     {
@@ -2344,7 +2365,7 @@ gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
         {
           /* If there's a toggle here, it isn't indexable so
              any_segment can't be the indexable segment. */
-          g_assert(real->any_segment != real->segment);
+          g_assert (real->any_segment != real->segment);
           return TRUE;
         }
     }
@@ -2354,7 +2375,7 @@ gtk_text_iter_forward_to_tag_toggle (GtkTextIter *iter,
     {
       /* If there's a toggle here, it isn't indexable so
          any_segment can't be the indexable segment. */
-      g_assert(real->any_segment != real->segment);
+      g_assert (real->any_segment != real->segment);
       return TRUE;
     }
   
index 4a53161ed2bbf02417e09b60665878677da77617..6cf14624ab035a20d439d8831bbf484e5d8e4b25 100644 (file)
@@ -59,7 +59,7 @@ gtk_text_mark_unref (GtkTextMark *mark)
 }
 
 gboolean
-gtk_text_mark_deleted (GtkTextMark *mark)
+gtk_text_mark_get_deleted (GtkTextMark *mark)
 {
   GtkTextLineSegment *seg;
   
@@ -79,14 +79,14 @@ gtk_text_mark_deleted (GtkTextMark *mark)
 
 
 GtkTextLineSegment*
-mark_segment_new(GtkTextBTree *tree,
-                 gboolean left_gravity,
-                 const gchar *name)
+mark_segment_new (GtkTextBTree *tree,
+                  gboolean left_gravity,
+                  const gchar *name)
 {
   GtkTextLineSegment *mark;
 
-  mark = (GtkTextLineSegment *) g_malloc0(MSEG_SIZE);
-  mark->body.mark.name = g_strdup(name);
+  mark = (GtkTextLineSegment *) g_malloc0 (MSEG_SIZE);
+  mark->body.mark.name = g_strdup (name);
 
   if (left_gravity)
     mark->type = &gtk_text_left_mark_type;
@@ -111,10 +111,10 @@ mark_segment_new(GtkTextBTree *tree,
 void
 mark_segment_ref(GtkTextLineSegment *mark)
 {
-  g_return_if_fail(mark != NULL);
-  g_return_if_fail(mark->type == &gtk_text_right_mark_type ||
-                   mark->type == &gtk_text_left_mark_type);
-  g_return_if_fail(mark->body.mark.refcount > 0);
+  g_return_if_fail (mark != NULL);
+  g_return_if_fail (mark->type == &gtk_text_right_mark_type ||
+                    mark->type == &gtk_text_left_mark_type);
+  g_return_if_fail (mark->body.mark.refcount > 0);
   
   mark->body.mark.refcount += 1;
 }
@@ -122,10 +122,10 @@ mark_segment_ref(GtkTextLineSegment *mark)
 void
 mark_segment_unref(GtkTextLineSegment *mark)
 {
-  g_return_if_fail(mark != NULL);
-  g_return_if_fail(mark->type == &gtk_text_right_mark_type ||
-                   mark->type == &gtk_text_left_mark_type);
-  g_return_if_fail(mark->body.mark.refcount > 0);
+  g_return_if_fail (mark != NULL);
+  g_return_if_fail (mark->type == &gtk_text_right_mark_type ||
+                    mark->type == &gtk_text_left_mark_type);
+  g_return_if_fail (mark->body.mark.refcount > 0);
 
   mark->body.mark.refcount -= 1;
 
@@ -137,17 +137,15 @@ mark_segment_unref(GtkTextLineSegment *mark)
     }
 }
 
-/*
- * Forward references for procedures defined in this file:
- */
 
-static int              mark_segment_delete_func  (GtkTextLineSegment   *segPtr,
-                                                   GtkTextLine      *line,
-                                                   int                treeGone);
-static GtkTextLineSegment *mark_segment_cleanup_func (GtkTextLineSegment   *segPtr,
-                                                   GtkTextLine      *line);
-static void             mark_segment_check_func   (GtkTextLineSegment   *segPtr,
-                                                   GtkTextLine      *line);
+static int                 mark_segment_delete_func  (GtkTextLineSegment *segPtr,
+                                                      GtkTextLine        *line,
+                                                      int                 treeGone);
+static GtkTextLineSegment *mark_segment_cleanup_func (GtkTextLineSegment *segPtr,
+                                                      GtkTextLine        *line);
+static void                mark_segment_check_func   (GtkTextLineSegment *segPtr,
+                                                      GtkTextLine        *line);
+
 
 /*
  * The following structures declare the "mark" segment types.
@@ -157,26 +155,25 @@ static void             mark_segment_check_func   (GtkTextLineSegment   *segPtr,
  */
 
 GtkTextLineSegmentClass gtk_text_right_mark_type = {
-    "mark",                                    /* name */
+    "mark",                                            /* name */
     FALSE,                                             /* leftGravity */
-    (GtkTextLineSegmentSplitFunc) NULL,                        /* splitFunc */
+    NULL,                                              /* splitFunc */
     mark_segment_delete_func,                          /* deleteFunc */
     mark_segment_cleanup_func,                         /* cleanupFunc */
-    (GtkTextLineSegmentLineChangeFunc) NULL,           /* lineChangeFunc */
+    NULL,                                              /* lineChangeFunc */
     mark_segment_check_func                            /* checkFunc */
 };
 
 GtkTextLineSegmentClass gtk_text_left_mark_type = {
-    "mark",                                    /* name */
+    "mark",                                            /* name */
     TRUE,                                              /* leftGravity */
-    (GtkTextLineSegmentSplitFunc) NULL,                        /* splitFunc */
+    NULL,                                              /* splitFunc */
     mark_segment_delete_func,                          /* deleteFunc */
     mark_segment_cleanup_func,                         /* cleanupFunc */
-    (GtkTextLineSegmentLineChangeFunc) NULL,           /* lineChangeFunc */
+    NULL,                                              /* lineChangeFunc */
     mark_segment_check_func                            /* checkFunc */
 };
 
-\f
 /*
  *--------------------------------------------------------------
  *
@@ -195,18 +192,14 @@ GtkTextLineSegmentClass gtk_text_left_mark_type = {
  *--------------------------------------------------------------
  */
 
-       /* ARGSUSED */
-static int
-mark_segment_delete_func(segPtr, line, treeGone)
-    GtkTextLineSegment *segPtr;                /* Segment being deleted. */
-    GtkTextLine *line;         /* Line containing segment. */
-    int treeGone;                      /* Non-zero means the entire tree is
-                                        * being deleted, so everything must
-                                        * get cleaned up. */
+static gboolean
+mark_segment_delete_func (GtkTextLineSegment *segPtr,
+                          GtkTextLine        *line,
+                          gboolean            tree_gone)
 {
-    return 1;
+  return TRUE;
 }
-\f
+
 /*
  *--------------------------------------------------------------
  *
@@ -225,112 +218,14 @@ mark_segment_delete_func(segPtr, line, treeGone)
  */
 
 static GtkTextLineSegment *
-mark_segment_cleanup_func(markPtr, line)
-    GtkTextLineSegment *markPtr;               /* Mark segment that's being moved. */
-    GtkTextLine *line;         /* Line that now contains segment. */
-{
-    markPtr->body.mark.line = line;
-    return markPtr;
-}
-
-#if 0
-
-\f
-/*
- *--------------------------------------------------------------
- *
- * GtkTextInsertDisplayFunc --
- *
- *     This procedure is called to display the insertion
- *     cursor.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Graphics are drawn.
- *
- *--------------------------------------------------------------
- */
-
-       /* ARGSUSED */
-void
-GtkTextInsertDisplayFunc(chunkPtr, x, y, height, baseline, display, dst, screenY)
-    GtkTextDisplayChunk *chunkPtr;             /* Chunk that is to be drawn. */
-    int x;                             /* X-position in dst at which to
-                                        * draw this chunk (may differ from
-                                        * the x-position in the chunk because
-                                        * of scrolling). */
-    int y;                             /* Y-position at which to draw this
-                                        * chunk in dst (x-position is in
-                                        * the chunk itself). */
-    int height;                                /* Total height of line. */
-    int baseline;                      /* Offset of baseline from y. */
-    Display *display;                  /* Display to use for drawing. */
-    Drawable dst;                      /* Pixmap or window in which to draw
-                                        * chunk. */
-    int screenY;                       /* Y-coordinate in text window that
-                                        * corresponds to y. */
+mark_segment_cleanup_func(GtkTextLineSegment *seg,
+                          GtkTextLine        *line)
 {
-    GtkTextView *tkxt = (GtkTextView *) chunkPtr->clientData;
-    int halfWidth = tkxt->insertWidth/2;
-
-    if ((x + halfWidth) < 0) {
-       /*
-        * The insertion cursor is off-screen.  Just return.
-        */
-
-       return;
-    }
-
-    /*
-     * As a special hack to keep the cursor visible on mono displays
-     * (or anywhere else that the selection and insertion cursors
-     * have the same color) write the default background in the cursor
-     * area (instead of nothing) when the cursor isn't on.  Otherwise
-     * the selection might hide the cursor.
-     */
-
-    if (tkxt->flags & INSERT_ON) {
-       Tk_Fill3DRectangle(tkxt->tkwin, dst, tkxt->insertBorder,
-               x - tkxt->insertWidth/2, y, tkxt->insertWidth,
-               height, tkxt->insertBorderWidth, TK_RELIEF_RAISED);
-    } else if (tkxt->selBorder == tkxt->insertBorder) {
-       Tk_Fill3DRectangle(tkxt->tkwin, dst, tkxt->border,
-               x - tkxt->insertWidth/2, y, tkxt->insertWidth,
-               height, 0, TK_RELIEF_FLAT);
-    }
+  /* not sure why Tk did this here and not in LineChangeFunc */
+  seg->body.mark.line = line;
+  return seg;
 }
-\f
-/*
- *--------------------------------------------------------------
- *
- * InsertUndisplayFunc --
- *
- *     This procedure is called when the insertion cursor is no
- *     longer at a visible point on the display.  It does nothing
- *     right now.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     None.
- *
- *--------------------------------------------------------------
- */
 
-       /* ARGSUSED */
-static void
-InsertUndisplayFunc(tkxt, chunkPtr)
-    GtkTextView *tkxt;                 /* Overall information about text
-                                        * widget. */
-    GtkTextDisplayChunk *chunkPtr;             /* Chunk that is about to be freed. */
-{
-    return;
-}
-\f
-#endif
 /*
  *--------------------------------------------------------------
  *
@@ -350,26 +245,9 @@ InsertUndisplayFunc(tkxt, chunkPtr)
  */
 
 static void
-mark_segment_check_func(markPtr, line)
-    GtkTextLineSegment *markPtr;               /* Segment to check. */
-    GtkTextLine *line;         /* Line containing segment. */
+mark_segment_check_func(GtkTextLineSegment *seg,
+                        GtkTextLine        *line)
 {
-    if (markPtr->body.mark.line != line)
-      g_error("mark_segment_check_func: markPtr->body.mark.line bogus");
-
-    /* No longer do this because we don't have access to btree
-       struct members */
-#if 0
-    /*
-     * Make sure that the mark is still present in the text's mark
-     * hash table.
-     */
-    for (hPtr = Tcl_FirstHashEntry(&markPtr->body.mark.tkxt->markTable,
-           &search); hPtr != markPtr->body.mark.hPtr;
-           hPtr = Tcl_NextHashEntry(&search)) {
-       if (hPtr == NULL) {
-           panic("mark_segment_check_func couldn't find hash table entry for mark");
-       }
-    }
-#endif
+  if (seg->body.mark.line != line)
+    g_error("mark_segment_check_func: seg->body.mark.line bogus");
 }
index feab32378dc0b6c0bd442d9059f04cda84006532..f2a0b5b796df084f1e5730727e76e20c607d75fa 100644 (file)
@@ -16,7 +16,7 @@ gboolean     gtk_text_mark_is_visible  (GtkTextMark *mark);
 const char * gtk_text_mark_get_name    (GtkTextMark *mark);
 GtkTextMark *gtk_text_mark_ref         (GtkTextMark *mark);
 void         gtk_text_mark_unref       (GtkTextMark *mark);
-gboolean     gtk_text_mark_deleted     (GtkTextMark *mark);
+gboolean     gtk_text_mark_get_deleted (GtkTextMark *mark);
 
 
 #ifdef __cplusplus
index 844663d4378eeec4f949834cf71cd581ce02289a..0dfd05630dc1099dc9a9112b8c88962327e15bee 100644 (file)
@@ -39,17 +39,36 @@ struct _GtkTextToggleBody {
 
 /* Class struct for segments */
 
-typedef GtkTextLineSegment *(* GtkTextLineSegmentSplitFunc)      (GtkTextLineSegment *segPtr,
-                                                        int index);
-typedef gboolean         (* GtkTextViewSegDeleteFunc)     (GtkTextLineSegment *segPtr,
-                                                        GtkTextLine *line,
-                                                        gboolean treeGone);
-typedef GtkTextLineSegment *(* GtkTextViewSegCleanupFunc)    (GtkTextLineSegment *segPtr,
-                                                        GtkTextLine *line);
-typedef void             (* GtkTextLineSegmentLineChangeFunc) (GtkTextLineSegment *segPtr,
-                                                        GtkTextLine *line);
-typedef void             (* GtkTextViewSegCheckFunc)      (GtkTextLineSegment *segPtr,
-                                                        GtkTextLine *line);
+/* Split seg at index, returning list of two new segments, and freeing seg */
+typedef GtkTextLineSegment* (*GtkTextSegSplitFunc)      (GtkTextLineSegment *seg,
+                                                         gint                index);
+
+/* Delete seg which is contained in line; if tree_gone, the tree is being
+ * freed in its entirety, which may matter for some reason (?)
+ * Return TRUE if the segment is not deleteable, e.g. a mark.
+ */
+typedef gboolean            (*GtkTextSegDeleteFunc)     (GtkTextLineSegment *seg,
+                                                         GtkTextLine        *line,
+                                                         gboolean            tree_gone);
+
+/* Called after segment structure of line changes, so segments can
+ * cleanup (e.g. merge with adjacent segments). Returns a segment list
+ * to replace the original segment list with. The line argument is
+ * the current line.
+ */
+typedef GtkTextLineSegment* (*GtkTextSegCleanupFunc)    (GtkTextLineSegment *seg,
+                                                         GtkTextLine        *line);
+
+/* Called when a segment moves from one line to another. CleanupFunc is also
+ * called in that case, so many segments just use CleanupFunc, I'm not sure
+ * what's up with that (this function may not be needed...)
+ */
+typedef void                (*GtkTextSegLineChangeFunc) (GtkTextLineSegment *seg,
+                                                         GtkTextLine        *line);
+
+/* Called to do debug checks on the segment. */
+typedef void                (*GtkTextSegCheckFunc)      (GtkTextLineSegment *seg,
+                                                         GtkTextLine        *line);
 
 struct _GtkTextLineSegmentClass {
   char *name;                           /* Name of this kind of segment. */
@@ -58,17 +77,17 @@ struct _GtkTextLineSegmentClass {
                                          * attach to character to its left
                                          * or right?  1 means left, 0 means
                                          * right. */
-  GtkTextLineSegmentSplitFunc splitFunc;       /* Procedure to split large segment
+  GtkTextSegSplitFunc splitFunc;        /* Procedure to split large segment
                                          * into two smaller ones. */
-  GtkTextViewSegDeleteFunc deleteFunc;     /* Procedure to call to delete
+  GtkTextSegDeleteFunc deleteFunc;      /* Procedure to call to delete
                                          * segment. */
-  GtkTextViewSegCleanupFunc cleanupFunc;   /* After any change to a line, this
+  GtkTextSegCleanupFunc cleanupFunc;   /* After any change to a line, this
                                          * procedure is invoked for all
                                          * segments left in the line to
                                          * perform any cleanup they wish
                                          * (e.g. joining neighboring
                                          * segments). */
-  GtkTextLineSegmentLineChangeFunc lineChangeFunc;
+  GtkTextSegLineChangeFunc lineChangeFunc;
                                          /* Invoked when a segment is about
                                           * to be moved from its current line
                                           * to an earlier line because of
@@ -77,7 +96,7 @@ struct _GtkTextLineSegmentClass {
                                           * CleanupFunc will be invoked after
                                           * the deletion is finished. */
 
-  GtkTextViewSegCheckFunc checkFunc;       /* Called during consistency checks
+  GtkTextSegCheckFunc checkFunc;       /* Called during consistency checks
                                          * to check internal consistency of
                                          * segment. */
 };
@@ -88,9 +107,9 @@ struct _GtkTextLineSegmentClass {
 
 struct _GtkTextLineSegment {
   GtkTextLineSegmentClass *type;                /* Pointer to record describing
-                                         * segment's type. */
+                                                 * segment's type. */
   GtkTextLineSegment *next;                /* Next in list of segments for this
-                                         * line, or NULL for end of list. */
+                                            * line, or NULL for end of list. */
 
   int char_count;                       /* # of chars of index space occupied */
   
index 3e198bed67077379f8da9794c4e75632c98741c3..fffa2bca3a57db20bda2bc3bd4cdaa598665d744 100644 (file)
@@ -721,7 +721,7 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
       gtk_text_buffer_get_iter_at_offset (text_view->buffer, &start, 0);
       
       text_view->dnd_mark = gtk_text_buffer_create_mark (text_view->buffer,
-                                                        "__drag_target",
+                                                        "gtk_drag_target",
                                                         &start, FALSE);
 
       text_view->first_para_mark = gtk_text_buffer_create_mark (text_view->buffer,
@@ -1866,7 +1866,7 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
   
   /* debug hack */
   if (event->button == 3 && (event->state & GDK_CONTROL_MASK) != 0)
-    gtk_text_buffer_spew (GTK_TEXT_VIEW (widget)->buffer);
+    _gtk_text_buffer_spew (GTK_TEXT_VIEW (widget)->buffer);
   else if (event->button == 3)
     gtk_text_layout_spew (GTK_TEXT_VIEW (widget)->layout);
 
@@ -3116,7 +3116,7 @@ gtk_text_view_drag_motion (GtkWidget        *widget,
 
   gtk_text_buffer_move_mark (text_view->buffer,
                              gtk_text_buffer_get_mark (text_view->buffer,
-                                                       "__drag_target"),
+                                                       "gtk_drag_target"),
                              &newplace);
 
   {
@@ -3130,7 +3130,7 @@ gtk_text_view_drag_motion (GtkWidget        *widget,
     
     gtk_text_view_scroll_to_mark_adjusted (text_view,
                                            gtk_text_buffer_get_mark (text_view->buffer,
-                                                                     "__drag_target"),
+                                                                     "gtk_drag_target"),
                                            margin, 1.0);
   }
   
@@ -3176,7 +3176,7 @@ gtk_text_view_drag_data_received (GtkWidget        *widget,
   text_view = GTK_TEXT_VIEW (widget);
   
   drag_target_mark = gtk_text_buffer_get_mark (text_view->buffer,
-                                               "__drag_target");
+                                               "gtk_drag_target");
   
   if (drag_target_mark == NULL)
     return;
index b787efe172e0e365e890d1a0dc66a9647e223c39..16e7172b768b4491f3e656b4142e62598f7096fe 100644 (file)
@@ -1433,6 +1433,35 @@ cursor_set_callback (GtkTextBuffer     *buffer,
     }
 }
 
+
+static void
+text_changed_callback (GtkTextBuffer     *buffer,
+                       gpointer           user_data)
+{
+  GtkTextView *text_view;
+
+  /* Redraw line number windows if the buffer changes
+   * and the widget is mapped (windows may not exist otherwise)
+   */
+  
+  text_view = GTK_TEXT_VIEW (user_data);
+  
+  if (GTK_WIDGET_MAPPED (text_view))
+    {
+      GdkWindow *line_window;
+
+      line_window = gtk_text_view_get_window (text_view,
+                                              GTK_TEXT_WINDOW_LEFT);
+      
+      gdk_window_invalidate_rect (line_window, NULL, FALSE);
+      
+      line_window = gtk_text_view_get_window (text_view,
+                                              GTK_TEXT_WINDOW_RIGHT);
+
+      gdk_window_invalidate_rect (line_window, NULL, FALSE);
+    }
+}
+
 static gint
 tab_stops_expose (GtkWidget      *widget,
                   GdkEventExpose *event,
@@ -1783,6 +1812,11 @@ create_view (Buffer *buffer)
                       "expose_event",
                       GTK_SIGNAL_FUNC (line_numbers_expose),
                       NULL);
+
+  gtk_signal_connect (GTK_OBJECT (view->buffer->buffer),
+                      "changed",
+                      GTK_SIGNAL_FUNC (text_changed_callback),
+                      view->text_view);
   
   gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
   gtk_container_add (GTK_CONTAINER (sw), view->text_view);
index b787efe172e0e365e890d1a0dc66a9647e223c39..16e7172b768b4491f3e656b4142e62598f7096fe 100644 (file)
@@ -1433,6 +1433,35 @@ cursor_set_callback (GtkTextBuffer     *buffer,
     }
 }
 
+
+static void
+text_changed_callback (GtkTextBuffer     *buffer,
+                       gpointer           user_data)
+{
+  GtkTextView *text_view;
+
+  /* Redraw line number windows if the buffer changes
+   * and the widget is mapped (windows may not exist otherwise)
+   */
+  
+  text_view = GTK_TEXT_VIEW (user_data);
+  
+  if (GTK_WIDGET_MAPPED (text_view))
+    {
+      GdkWindow *line_window;
+
+      line_window = gtk_text_view_get_window (text_view,
+                                              GTK_TEXT_WINDOW_LEFT);
+      
+      gdk_window_invalidate_rect (line_window, NULL, FALSE);
+      
+      line_window = gtk_text_view_get_window (text_view,
+                                              GTK_TEXT_WINDOW_RIGHT);
+
+      gdk_window_invalidate_rect (line_window, NULL, FALSE);
+    }
+}
+
 static gint
 tab_stops_expose (GtkWidget      *widget,
                   GdkEventExpose *event,
@@ -1783,6 +1812,11 @@ create_view (Buffer *buffer)
                       "expose_event",
                       GTK_SIGNAL_FUNC (line_numbers_expose),
                       NULL);
+
+  gtk_signal_connect (GTK_OBJECT (view->buffer->buffer),
+                      "changed",
+                      GTK_SIGNAL_FUNC (text_changed_callback),
+                      view->text_view);
   
   gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
   gtk_container_add (GTK_CONTAINER (sw), view->text_view);